<template>
  <transition
    enter-active-class="transition duration-300 ease-out"
    enter-from-class="transform translate-y-2 opacity-0"
    enter-to-class="transform translate-y-0 opacity-100"
    leave-active-class="transition duration-200 ease-in"
    leave-from-class="transform translate-y-0 opacity-100"
    leave-to-class="transform translate-y-2 opacity-0"
  >
    <div
      v-if="show"
      class="fixed bottom-4 right-4 z-50 max-w-sm w-full"
    >
      <div
        class="rounded-lg shadow-lg p-4 border"
        :class="toastClasses"
      >
        <div class="flex items-start">
          <div class="flex-shrink-0">
            <component
              :is="iconComponent"
              class="h-6 w-6"
              :class="iconColorClass"
            />
          </div>
          <div class="ml-3 w-0 flex-1">
            <p
              v-if="title"
              class="text-sm font-medium"
              :class="textColorClass"
            >
              {{ title }}
            </p>
            <p
              v-if="message"
              class="text-sm mt-1"
              :class="textColorClass"
            >
              {{ message }}
            </p>
          </div>
          <div class="ml-4 flex-shrink-0 flex">
            <button
              @click="close"
              class="inline-flex rounded-md hover:opacity-75 focus:outline-none focus:ring-2 focus:ring-offset-2"
              :class="focusRingClass"
            >
              <X class="h-5 w-5" :class="iconColorClass" />
            </button>
          </div>
        </div>
      </div>
    </div>
  </transition>
</template>

<script setup lang="ts">
import { computed, onMounted, onUnmounted } from 'vue'
import {
  CheckCircle,
  AlertCircle,
  AlertTriangle,
  Info,
  X
} from 'lucide-vue-next'

interface Props {
  type: 'success' | 'error' | 'warning' | 'info'
  title?: string
  message?: string
  duration?: number
  show: boolean
}

const props = withDefaults(defineProps<Props>(), {
  duration: 5000
})

const emit = defineEmits<{
  close: []
}>()

let timer: number | null = null

const toastClasses = computed(() => {
  switch (props.type) {
    case 'success':
      return 'bg-green-50 border-green-200'
    case 'error':
      return 'bg-red-50 border-red-200'
    case 'warning':
      return 'bg-yellow-50 border-yellow-200'
    case 'info':
      return 'bg-blue-50 border-blue-200'
    default:
      return 'bg-white border-gray-200'
  }
})

const iconComponent = computed(() => {
  switch (props.type) {
    case 'success':
      return CheckCircle
    case 'error':
      return AlertCircle
    case 'warning':
      return AlertTriangle
    case 'info':
      return Info
    default:
      return Info
  }
})

const iconColorClass = computed(() => {
  switch (props.type) {
    case 'success':
      return 'text-green-600'
    case 'error':
      return 'text-red-600'
    case 'warning':
      return 'text-yellow-600'
    case 'info':
      return 'text-blue-600'
    default:
      return 'text-gray-600'
  }
})

const textColorClass = computed(() => {
  switch (props.type) {
    case 'success':
      return 'text-green-800'
    case 'error':
      return 'text-red-800'
    case 'warning':
      return 'text-yellow-800'
    case 'info':
      return 'text-blue-800'
    default:
      return 'text-gray-800'
  }
})

const focusRingClass = computed(() => {
  switch (props.type) {
    case 'success':
      return 'focus:ring-green-500'
    case 'error':
      return 'focus:ring-red-500'
    case 'warning':
      return 'focus:ring-yellow-500'
    case 'info':
      return 'focus:ring-blue-500'
    default:
      return 'focus:ring-gray-500'
  }
})

const close = () => {
  emit('close')
}

const startTimer = () => {
  if (props.duration > 0) {
    timer = window.setTimeout(() => {
      close()
    }, props.duration)
  }
}

const clearTimer = () => {
  if (timer) {
    clearTimeout(timer)
    timer = null
  }
}

onMounted(() => {
  startTimer()
})

onUnmounted(() => {
  clearTimer()
})
</script>